package com.sfeir.server.dao;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.google.appengine.api.datastore.EntityNotFoundException;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Query;
import com.googlecode.objectify.util.DAOBase;
import com.sfeir.shared.Level;
import com.sfeir.shared.MatrixPoint;

/**
 * Level Dao Implementation
 * 
 * @author Oussama Zoghlami
 * 
 */
public class LevelDao extends DAOBase {

	public LevelDao() {
	}

	/**
	 * 
	 * @param level
	 * @return level key
	 */
	public Key<Level> add(Level level) {
		updateLevelJsonData(level, false);
		Key<Level> key = ofy().put(level);
		return key;
	}

	/**
	 * 
	 * @param id
	 * @return
	 * @throws EntityNotFoundException
	 */
	public Level get(Long id) throws EntityNotFoundException {
		Level level = ofy().get(Level.class, id);
		updateLevelJsonData(level, true);
		return level;
	}

	/**
	 * 
	 * @return
	 */
	public List<Level> getAll() {
		Query<Level> q = ofy().query(Level.class);
		q.order("order");
		List<Level> levels = q.list();
		for (Level level : levels) {
			updateLevelJsonData(level, true);
		}
		return levels;
	}

	/**
	 * 
	 * @param level
	 */
	public void delete(Level level) {
		ofy().delete(level);
	}

	/**
	 * 
	 * @param levels
	 */
	public void delete(List<Level> levels) {
		for (Level level : levels) {
			delete(level);
		}
	}

	/**
	 * 
	 * @param levelKey
	 */
	public void delete(Key<Level> levelKey) {
		ofy().delete(levelKey);
	}

	/**
	 * Method allowing to initialize the game levels
	 */
	public void initializeLevelData() {
		List<Level> levels = getAll();
		if (levels.size() > 0) {
			return ;
//			delete(levels);
		}

		List<Level> initLevels = constructGameLevel();
		for (Level level : initLevels) {
			add(level);
		}
	}

	/**
	 * 
	 * @return
	 */
	private List<Level> constructGameLevel() {
		// Level 1
		List<MatrixPoint> plateau = new ArrayList<MatrixPoint>();
		plateau.add(new MatrixPoint(19, 0, 2));
		plateau.add(new MatrixPoint(19, 1, 2));
		plateau.add(new MatrixPoint(19, 2, 2));
		plateau.add(new MatrixPoint(19, 3, 2));
		plateau.add(new MatrixPoint(19, 4, 2));
		plateau.add(new MatrixPoint(19, 5, 2));
		plateau.add(new MatrixPoint(19, 6, 2));
		plateau.add(new MatrixPoint(19, 8, 2));
		plateau.add(new MatrixPoint(19, 9, 2));
		plateau.add(new MatrixPoint(18, 0, 2));
		plateau.add(new MatrixPoint(18, 1, 2));
		plateau.add(new MatrixPoint(18, 2, 2));
		plateau.add(new MatrixPoint(18, 3, 2));
		plateau.add(new MatrixPoint(18, 4, 2));
		plateau.add(new MatrixPoint(18, 5, 2));
		plateau.add(new MatrixPoint(18, 6, 2));
		plateau.add(new MatrixPoint(18, 8, 2));
		plateau.add(new MatrixPoint(18, 9, 2));
		plateau.add(new MatrixPoint(17, 0, 2));
		plateau.add(new MatrixPoint(17, 1, 2));
		plateau.add(new MatrixPoint(17, 2, 2));
		plateau.add(new MatrixPoint(17, 3, 2));
		plateau.add(new MatrixPoint(17, 4, 2));
		plateau.add(new MatrixPoint(17, 5, 2));
		plateau.add(new MatrixPoint(17, 6, 2));
		plateau.add(new MatrixPoint(17, 9, 2));

		List<Integer> sequence = new ArrayList<Integer>();
		sequence.add(5);

		Level level = new Level(1, sequence, plateau);

		// Level 2
		List<MatrixPoint> plateau2 = new ArrayList<MatrixPoint>();
		plateau2.add(new MatrixPoint(19, 0, 2));
		plateau2.add(new MatrixPoint(19, 1, 2));
		plateau2.add(new MatrixPoint(19, 2, 2));
		plateau2.add(new MatrixPoint(19, 3, 2));
		plateau2.add(new MatrixPoint(19, 4, 2));
		plateau2.add(new MatrixPoint(19, 5, 2));
		plateau2.add(new MatrixPoint(19, 6, 2));
		plateau2.add(new MatrixPoint(19, 8, 2));
		plateau2.add(new MatrixPoint(18, 0, 2));
		plateau2.add(new MatrixPoint(18, 1, 2));
		plateau2.add(new MatrixPoint(18, 2, 2));
		plateau2.add(new MatrixPoint(18, 3, 2));
		plateau2.add(new MatrixPoint(18, 4, 2));
		plateau2.add(new MatrixPoint(18, 5, 2));
		plateau2.add(new MatrixPoint(18, 6, 2));
		plateau2.add(new MatrixPoint(17, 0, 2));
		plateau2.add(new MatrixPoint(17, 1, 2));
		plateau2.add(new MatrixPoint(17, 2, 2));
		plateau2.add(new MatrixPoint(17, 3, 2));
		plateau2.add(new MatrixPoint(17, 4, 2));
		plateau2.add(new MatrixPoint(17, 5, 2));
		plateau2.add(new MatrixPoint(17, 6, 2));

		List<Integer> sequence2 = new ArrayList<Integer>();
		sequence2.add(6);
		sequence2.add(5);

		Level level2 = new Level(2, sequence2, plateau2);

		// Level 3
		List<MatrixPoint> plateau3 = new ArrayList<MatrixPoint>();
		plateau3.add(new MatrixPoint(19, 0, 2));
		plateau3.add(new MatrixPoint(19, 1, 2));
		plateau3.add(new MatrixPoint(19, 2, 2));
		plateau3.add(new MatrixPoint(19, 3, 2));
		plateau3.add(new MatrixPoint(19, 4, 2));
		plateau3.add(new MatrixPoint(19, 5, 2));
		plateau3.add(new MatrixPoint(19, 8, 2));
		plateau3.add(new MatrixPoint(18, 0, 2));
		plateau3.add(new MatrixPoint(18, 1, 2));
		plateau3.add(new MatrixPoint(18, 2, 2));
		plateau3.add(new MatrixPoint(18, 3, 2));
		plateau3.add(new MatrixPoint(18, 4, 2));
		plateau3.add(new MatrixPoint(18, 5, 2));
		plateau3.add(new MatrixPoint(17, 0, 2));
		plateau3.add(new MatrixPoint(17, 1, 2));
		plateau3.add(new MatrixPoint(17, 2, 2));
		plateau3.add(new MatrixPoint(17, 3, 2));
		plateau3.add(new MatrixPoint(17, 4, 2));

		List<Integer> sequence3 = new ArrayList<Integer>();
		sequence3.add(6);
		sequence3.add(5);
		sequence3.add(3);

		Level level3 = new Level(3, sequence3, plateau3);

		// Level 4
		List<MatrixPoint> plateau4 = new ArrayList<MatrixPoint>();
		plateau4.add(new MatrixPoint(19, 0, 2));
		plateau4.add(new MatrixPoint(19, 1, 2));
		plateau4.add(new MatrixPoint(19, 2, 2));
		plateau4.add(new MatrixPoint(19, 3, 2));
		plateau4.add(new MatrixPoint(19, 4, 2));
		plateau4.add(new MatrixPoint(19, 8, 2));
		plateau4.add(new MatrixPoint(18, 0, 2));
		plateau4.add(new MatrixPoint(18, 1, 2));
		plateau4.add(new MatrixPoint(18, 2, 2));
		plateau4.add(new MatrixPoint(18, 3, 2));
		plateau4.add(new MatrixPoint(17, 0, 2));
		plateau4.add(new MatrixPoint(17, 1, 2));
		plateau4.add(new MatrixPoint(17, 2, 2));
		plateau4.add(new MatrixPoint(17, 3, 2));

		List<Integer> sequence4 = new ArrayList<Integer>();
		sequence4.add(6);
		sequence4.add(5);
		sequence4.add(2);
		sequence4.add(3);

		Level level4 = new Level(4, sequence4, plateau4);

		// Level 5
		List<MatrixPoint> plateau5 = new ArrayList<MatrixPoint>();
		plateau5.add(new MatrixPoint(19, 0, 2));
		plateau5.add(new MatrixPoint(19, 1, 2));
		plateau5.add(new MatrixPoint(19, 2, 2));
		plateau5.add(new MatrixPoint(19, 8, 2));
		plateau5.add(new MatrixPoint(18, 0, 2));
		plateau5.add(new MatrixPoint(18, 1, 2));
		plateau5.add(new MatrixPoint(18, 2, 2));
		plateau5.add(new MatrixPoint(17, 0, 2));
		plateau5.add(new MatrixPoint(17, 1, 2));
		plateau5.add(new MatrixPoint(17, 2, 2));

		List<Integer> sequence5 = new ArrayList<Integer>();
		sequence5.add(6);
		sequence5.add(5);
		sequence5.add(3);
		sequence5.add(2);
		sequence5.add(3);

		Level level5 = new Level(5, sequence5, plateau5);

		// Level 6
		List<MatrixPoint> plateau6 = new ArrayList<MatrixPoint>();
		plateau6.add(new MatrixPoint(19, 0, 2));
		plateau6.add(new MatrixPoint(19, 1, 2));
		plateau6.add(new MatrixPoint(19, 8, 2));
		plateau6.add(new MatrixPoint(18, 0, 2));
		plateau6.add(new MatrixPoint(18, 1, 2));
		plateau6.add(new MatrixPoint(17, 0, 2));

		List<Integer> sequence6 = new ArrayList<Integer>();
		sequence6.add(6);
		sequence6.add(5);
		sequence6.add(2);
		sequence6.add(3);
		sequence6.add(3);
		sequence6.add(3);

		Level level6 = new Level(6, sequence6, plateau6);

		// Level 7
		List<MatrixPoint> plateau7 = new ArrayList<MatrixPoint>();
		plateau7.add(new MatrixPoint(19, 1, 2));
		plateau7.add(new MatrixPoint(19, 8, 2));

		List<Integer> sequence7 = new ArrayList<Integer>();
		sequence7.add(6);
		sequence7.add(6);
		sequence7.add(5);
		sequence7.add(3);
		sequence7.add(2);
		sequence7.add(3);
		sequence7.add(3);

		Level level7 = new Level(7, sequence7, plateau7);

		// Level 8
		List<MatrixPoint> plateau8 = new ArrayList<MatrixPoint>();
		plateau8.add(new MatrixPoint(19, 3, 2));
		plateau8.add(new MatrixPoint(19, 4, 2));
		plateau8.add(new MatrixPoint(19, 5, 2));
		plateau8.add(new MatrixPoint(19, 6, 2));
		plateau8.add(new MatrixPoint(19, 7, 2));
		plateau8.add(new MatrixPoint(19, 8, 2));
		plateau8.add(new MatrixPoint(19, 9, 2));
		plateau8.add(new MatrixPoint(18, 8, 2));

		List<Integer> sequence8 = new ArrayList<Integer>();
		sequence8.add(6);
		sequence8.add(6);
		sequence8.add(6);
		sequence8.add(3);
		sequence8.add(5);
		sequence8.add(3);
		sequence8.add(2);
		sequence8.add(3);

		Level level8 = new Level(8, sequence8, plateau8);

		// Level 9
		List<MatrixPoint> plateau9 = new ArrayList<MatrixPoint>();
		plateau9.add(new MatrixPoint(19, 7, 2));
		plateau9.add(new MatrixPoint(19, 8, 2));
		plateau9.add(new MatrixPoint(19, 9, 2));
		plateau9.add(new MatrixPoint(18, 8, 2));

		List<Integer> sequence9 = new ArrayList<Integer>();
		sequence9.add(7);
		sequence9.add(6);
		sequence9.add(6);
		sequence9.add(6);
		sequence9.add(3);
		sequence9.add(3);
		sequence9.add(2);
		sequence9.add(3);
		sequence9.add(5);

		Level level9 = new Level(9, sequence9, plateau9);

		// Level 10
		List<MatrixPoint> plateau10 = new ArrayList<MatrixPoint>();

		List<Integer> sequence10 = new ArrayList<Integer>();
		sequence10.add(6);
		sequence10.add(7);
		sequence10.add(6);
		sequence10.add(6);
		sequence10.add(3);
		sequence10.add(6);
		sequence10.add(5);
		sequence10.add(3);
		sequence10.add(2);
		sequence10.add(3);

		Level level10 = new Level(10, sequence10, plateau10);

		// Level 11
		List<MatrixPoint> plateau11 = new ArrayList<MatrixPoint>();
		plateau11.add(new MatrixPoint(19, 0, 2));
		plateau11.add(new MatrixPoint(19, 1, 2));
		plateau11.add(new MatrixPoint(19, 2, 2));
		plateau11.add(new MatrixPoint(19, 3, 2));
		plateau11.add(new MatrixPoint(19, 4, 2));
		plateau11.add(new MatrixPoint(19, 5, 2));
		plateau11.add(new MatrixPoint(19, 6, 2));
		plateau11.add(new MatrixPoint(19, 7, 2));
		plateau11.add(new MatrixPoint(18, 0, 2));
		plateau11.add(new MatrixPoint(18, 1, 2));
		plateau11.add(new MatrixPoint(18, 2, 2));
		plateau11.add(new MatrixPoint(18, 3, 2));
		plateau11.add(new MatrixPoint(18, 4, 2));
		plateau11.add(new MatrixPoint(18, 5, 2));
		plateau11.add(new MatrixPoint(18, 6, 2));
		plateau11.add(new MatrixPoint(18, 7, 2));

		List<Integer> sequence11 = new ArrayList<Integer>();
		sequence11.add(1);
		sequence11.add(6);
		sequence11.add(6);
		sequence11.add(6);
		sequence11.add(6);
		sequence11.add(5);
		sequence11.add(7);
		sequence11.add(2);
		sequence11.add(3);
		sequence11.add(3);
		sequence11.add(3);

		Level level11 = new Level(11, sequence11, plateau11);

		// Level 12
		List<MatrixPoint> plateau12 = new ArrayList<MatrixPoint>();
		plateau12.add(new MatrixPoint(19, 0, 2));
		plateau12.add(new MatrixPoint(19, 1, 2));
		plateau12.add(new MatrixPoint(19, 2, 2));
		plateau12.add(new MatrixPoint(19, 3, 2));
		plateau12.add(new MatrixPoint(19, 5, 2));
		plateau12.add(new MatrixPoint(19, 6, 2));
		plateau12.add(new MatrixPoint(19, 7, 2));
		plateau12.add(new MatrixPoint(18, 0, 2));
		plateau12.add(new MatrixPoint(18, 1, 2));
		plateau12.add(new MatrixPoint(18, 2, 2));
		plateau12.add(new MatrixPoint(18, 6, 2));
		plateau12.add(new MatrixPoint(18, 7, 2));

		List<Integer> sequence12 = new ArrayList<Integer>();
		sequence12.add(6);
		sequence12.add(1);
		sequence12.add(7);
		sequence12.add(6);
		sequence12.add(6);
		sequence12.add(5);
		sequence12.add(3);
		sequence12.add(2);
		sequence12.add(3);
		sequence12.add(6);
		sequence12.add(6);
		sequence12.add(3);

		Level level12 = new Level(12, sequence12, plateau12);

		// Level 13
		List<MatrixPoint> plateau13 = new ArrayList<MatrixPoint>();
		plateau13.add(new MatrixPoint(19, 0, 2));
		plateau13.add(new MatrixPoint(19, 1, 2));
		plateau13.add(new MatrixPoint(19, 2, 2));
		plateau13.add(new MatrixPoint(19, 3, 2));
		plateau13.add(new MatrixPoint(19, 7, 2));
		plateau13.add(new MatrixPoint(18, 0, 2));
		plateau13.add(new MatrixPoint(18, 1, 2));
		plateau13.add(new MatrixPoint(18, 2, 2));

		List<Integer> sequence13 = new ArrayList<Integer>();
		sequence13.add(2);
		sequence13.add(1);
		sequence13.add(6);
		sequence13.add(6);
		sequence13.add(6);
		sequence13.add(7);
		sequence13.add(3);
		sequence13.add(6);
		sequence13.add(6);
		sequence13.add(3);
		sequence13.add(5);
		sequence13.add(2);
		sequence13.add(3);

		Level level13 = new Level(13, sequence13, plateau13);
		
		// Level 14
		List<MatrixPoint> plateau14 = new ArrayList<MatrixPoint>();
		plateau14.add(new MatrixPoint(19, 0, 2));
		plateau14.add(new MatrixPoint(19, 1, 2));
		plateau14.add(new MatrixPoint(19, 3, 2));
		plateau14.add(new MatrixPoint(19, 7, 2));

		List<Integer> sequence14 = new ArrayList<Integer>();
		sequence14.add(2);
		sequence14.add(6);
		sequence14.add(7);
		sequence14.add(1);
		sequence14.add(6);
		sequence14.add(6);
		sequence14.add(5);
		sequence14.add(3);
		sequence14.add(2);
		sequence14.add(5);
		sequence14.add(3);
		sequence14.add(6);
		sequence14.add(6);
		sequence14.add(3);

		Level level14 = new Level(14, sequence14, plateau14);
		
		// Level 15
		List<MatrixPoint> plateau15 = new ArrayList<MatrixPoint>();
		plateau15.add(new MatrixPoint(18, 0, 2));
		plateau15.add(new MatrixPoint(18, 1, 2));
		plateau15.add(new MatrixPoint(18, 3, 2));
		plateau15.add(new MatrixPoint(19, 0, 2));
		plateau15.add(new MatrixPoint(19, 1, 2));
		plateau15.add(new MatrixPoint(19, 2, 2));
		plateau15.add(new MatrixPoint(19, 3, 2));
		plateau15.add(new MatrixPoint(19, 4, 2));
		plateau15.add(new MatrixPoint(19, 5, 2));
		plateau15.add(new MatrixPoint(19, 6, 2));

		List<Integer> sequence15 = new ArrayList<Integer>();
		sequence15.add(5);
		sequence15.add(6);
		sequence15.add(6);
		sequence15.add(3);
		sequence15.add(5);
		sequence15.add(1);
		sequence15.add(2);
		sequence15.add(6);
		sequence15.add(6);
		sequence15.add(7);
		sequence15.add(3);
		sequence15.add(2);
		sequence15.add(6);
		sequence15.add(5);
		sequence15.add(3);

		Level level15 = new Level(15, sequence15, plateau15);

		// Level 16
		List<MatrixPoint> plateau16 = new ArrayList<MatrixPoint>();
		plateau16.add(new MatrixPoint(18, 3, 2));
		plateau16.add(new MatrixPoint(19, 0, 2));
		plateau16.add(new MatrixPoint(19, 3, 2));
		plateau16.add(new MatrixPoint(19, 4, 2));
		plateau16.add(new MatrixPoint(19, 5, 2));
		plateau16.add(new MatrixPoint(19, 6, 2));

		List<Integer> sequence16 = new ArrayList<Integer>();
		sequence16.add(4);
		sequence16.add(5);
		sequence16.add(2);
		sequence16.add(1);
		sequence16.add(6);
		sequence16.add(5);
		sequence16.add(6);
		sequence16.add(6);
		sequence16.add(6);
		sequence16.add(6);
		sequence16.add(7);
		sequence16.add(2);
		sequence16.add(3);
		sequence16.add(3);
		sequence16.add(3);
		sequence16.add(5);

		Level level16 = new Level(16, sequence16, plateau16);
		
		// Level 17
		List<MatrixPoint> plateau17 = new ArrayList<MatrixPoint>();
		plateau17.add(new MatrixPoint(19, 0, 2));
		plateau17.add(new MatrixPoint(19, 1, 2));
		plateau17.add(new MatrixPoint(19, 2, 2));
		plateau17.add(new MatrixPoint(19, 3, 2));
		plateau17.add(new MatrixPoint(19, 5, 2));
		plateau17.add(new MatrixPoint(19, 6, 2));
		plateau17.add(new MatrixPoint(19, 7, 2));
		plateau17.add(new MatrixPoint(19, 8, 2));
		plateau17.add(new MatrixPoint(19, 9, 2));
		plateau17.add(new MatrixPoint(18, 0, 2));
		plateau17.add(new MatrixPoint(18, 5, 2));
		plateau17.add(new MatrixPoint(18, 6, 2));

		List<Integer> sequence17 = new ArrayList<Integer>();
		sequence17.add(5);
		sequence17.add(2);
		sequence17.add(2);
		sequence17.add(6);
		sequence17.add(4);
		sequence17.add(1);
		sequence17.add(6);
		sequence17.add(6);
		sequence17.add(5);
		sequence17.add(7);
		sequence17.add(5);
		sequence17.add(3);
		sequence17.add(2);
		sequence17.add(3);
		sequence17.add(6);
		sequence17.add(6);
		sequence17.add(3);

		Level level17 = new Level(17, sequence17, plateau17);
		
		// Level 18
		List<MatrixPoint> plateau18 = new ArrayList<MatrixPoint>();
		plateau18.add(new MatrixPoint(19, 3, 2));
		plateau18.add(new MatrixPoint(19, 5, 2));
		plateau18.add(new MatrixPoint(19, 6, 2));
		plateau18.add(new MatrixPoint(19, 7, 2));
		plateau18.add(new MatrixPoint(19, 8, 2));
		plateau18.add(new MatrixPoint(19, 9, 2));
		plateau18.add(new MatrixPoint(18, 5, 2));
		plateau18.add(new MatrixPoint(18, 6, 2));

		List<Integer> sequence18 = new ArrayList<Integer>();
		sequence18.add(5);
		sequence18.add(2);
		sequence18.add(5);
		sequence18.add(1);
		sequence18.add(4);
		sequence18.add(2);
		sequence18.add(6);
		sequence18.add(5);
		sequence18.add(6);
		sequence18.add(6);
		sequence18.add(3);
		sequence18.add(7);
		sequence18.add(3);
		sequence18.add(2);
		sequence18.add(3);
		sequence18.add(6);
		sequence18.add(6);
		sequence18.add(5);

		Level level18 = new Level(18, sequence18, plateau18);

		// Level 19
		List<MatrixPoint> plateau19 = new ArrayList<MatrixPoint>();
		plateau19.add(new MatrixPoint(19, 0, 2));
		plateau19.add(new MatrixPoint(19, 1, 2));
		plateau19.add(new MatrixPoint(19, 2, 2));
		plateau19.add(new MatrixPoint(19, 3, 2));
		plateau19.add(new MatrixPoint(19, 4, 2));
		plateau19.add(new MatrixPoint(19, 6, 2));
		plateau19.add(new MatrixPoint(19, 7, 2));
		plateau19.add(new MatrixPoint(19, 8, 2));
		plateau19.add(new MatrixPoint(19, 9, 2));
		plateau19.add(new MatrixPoint(18, 3, 2));
		plateau19.add(new MatrixPoint(18, 6, 2));
		plateau19.add(new MatrixPoint(18, 7, 2));
		plateau19.add(new MatrixPoint(18, 8, 2));
		plateau19.add(new MatrixPoint(18, 9, 2));

		List<Integer> sequence19 = new ArrayList<Integer>();
		sequence19.add(2);
		sequence19.add(5);
		sequence19.add(5);
		sequence19.add(2);
		sequence19.add(6);
		sequence19.add(7);
		sequence19.add(5);
		sequence19.add(1);
		sequence19.add(6);
		sequence19.add(4);
		sequence19.add(3);
		sequence19.add(5);
		sequence19.add(6);
		sequence19.add(5);
		sequence19.add(2);
		sequence19.add(6);
		sequence19.add(3);
		sequence19.add(6);
		sequence19.add(3);

		Level level19 = new Level(19, sequence19, plateau19);

		// Level 20
		List<MatrixPoint> plateau20 = new ArrayList<MatrixPoint>();
		plateau20.add(new MatrixPoint(19, 0, 2));
		plateau20.add(new MatrixPoint(19, 1, 2));
		plateau20.add(new MatrixPoint(19, 6, 2));
		plateau20.add(new MatrixPoint(19, 7, 2));
		plateau20.add(new MatrixPoint(19, 8, 2));
		plateau20.add(new MatrixPoint(19, 9, 2));
		plateau20.add(new MatrixPoint(18, 6, 2));
		plateau20.add(new MatrixPoint(18, 7, 2));
		plateau20.add(new MatrixPoint(18, 8, 2));
		plateau20.add(new MatrixPoint(18, 9, 2));

		List<Integer> sequence20 = new ArrayList<Integer>();
		sequence20.add(5);
		sequence20.add(6);
		sequence20.add(5);
		sequence20.add(2);
		sequence20.add(5);
		sequence20.add(4);
		sequence20.add(2);
		sequence20.add(6);
		sequence20.add(5);
		sequence20.add(6);
		sequence20.add(7);
		sequence20.add(2);
		sequence20.add(3);
		sequence20.add(1);
		sequence20.add(6);
		sequence20.add(3);
		sequence20.add(6);
		sequence20.add(5);
		sequence20.add(6);
		sequence20.add(3);

		Level level20 = new Level(20, sequence20, plateau20);

		// Level 21
		List<MatrixPoint> plateau21 = new ArrayList<MatrixPoint>();
		plateau21.add(new MatrixPoint(19, 2, 2));
		plateau21.add(new MatrixPoint(19, 3, 2));
		plateau21.add(new MatrixPoint(19, 4, 2));
		plateau21.add(new MatrixPoint(19, 5, 2));
		plateau21.add(new MatrixPoint(19, 6, 2));
		plateau21.add(new MatrixPoint(19, 7, 2));
		plateau21.add(new MatrixPoint(19, 8, 2));
		plateau21.add(new MatrixPoint(19, 9, 2));
		plateau21.add(new MatrixPoint(18, 6, 2));
		plateau21.add(new MatrixPoint(18, 7, 2));
		plateau21.add(new MatrixPoint(18, 8, 2));
		plateau21.add(new MatrixPoint(18, 9, 2));
		plateau21.add(new MatrixPoint(17, 6, 2));
		plateau21.add(new MatrixPoint(17, 7, 2));
		plateau21.add(new MatrixPoint(17, 8, 2));
		plateau21.add(new MatrixPoint(17, 9, 2));

		List<Integer> sequence21 = new ArrayList<Integer>();
		sequence21.add(6);
		sequence21.add(2);
		sequence21.add(5);
		sequence21.add(5);
		sequence21.add(2);
		sequence21.add(6);
		sequence21.add(7);
		sequence21.add(2);
		sequence21.add(3);
		sequence21.add(3);
		sequence21.add(1);
		sequence21.add(6);
		sequence21.add(6);
		sequence21.add(5);
		sequence21.add(1);
		sequence21.add(5);
		sequence21.add(4);
		sequence21.add(5);
		sequence21.add(6);
		sequence21.add(6);
		sequence21.add(3);

		Level level21 = new Level(21, sequence21, plateau21);

		// Level 22
		List<MatrixPoint> plateau22 = new ArrayList<MatrixPoint>();
		plateau22.add(new MatrixPoint(19, 2, 2));
		plateau22.add(new MatrixPoint(19, 3, 2));
		plateau22.add(new MatrixPoint(19, 4, 2));
		plateau22.add(new MatrixPoint(19, 5, 2));
		plateau22.add(new MatrixPoint(19, 6, 2));
		plateau22.add(new MatrixPoint(19, 7, 2));
		plateau22.add(new MatrixPoint(19, 8, 2));
		plateau22.add(new MatrixPoint(18, 6, 2));
		plateau22.add(new MatrixPoint(18, 7, 2));
		plateau22.add(new MatrixPoint(18, 8, 2));
		plateau22.add(new MatrixPoint(17, 6, 2));
		plateau22.add(new MatrixPoint(17, 7, 2));

		List<Integer> sequence22 = new ArrayList<Integer>();
		sequence22.add(6);
		sequence22.add(1);
		sequence22.add(5);
		sequence22.add(4);
		sequence22.add(5);
		sequence22.add(6);
		sequence22.add(6);
		sequence22.add(3);
		sequence22.add(2);
		sequence22.add(5);
		sequence22.add(3);
		sequence22.add(5);
		sequence22.add(2);
		sequence22.add(1);
		sequence22.add(6);
		sequence22.add(6);
		sequence22.add(5);
		sequence22.add(6);
		sequence22.add(7);
		sequence22.add(3);
		sequence22.add(2);
		sequence22.add(3);

		Level level22 = new Level(22, sequence22, plateau22);

		// Level 23
		List<MatrixPoint> plateau23 = new ArrayList<MatrixPoint>();
		plateau23.add(new MatrixPoint(19, 2, 2));
		plateau23.add(new MatrixPoint(19, 3, 2));
		plateau23.add(new MatrixPoint(19, 4, 2));
		plateau23.add(new MatrixPoint(19, 5, 2));
		plateau23.add(new MatrixPoint(19, 7, 2));
		plateau23.add(new MatrixPoint(19, 8, 2));
		plateau23.add(new MatrixPoint(18, 7, 2));
		plateau23.add(new MatrixPoint(18, 8, 2));

		List<Integer> sequence23 = new ArrayList<Integer>();
		sequence23.add(1);
		sequence23.add(6);
		sequence23.add(2);
		sequence23.add(3);
		sequence23.add(5);
		sequence23.add(5);
		sequence23.add(5);
		sequence23.add(1);
		sequence23.add(5);
		sequence23.add(4);
		sequence23.add(2);
		sequence23.add(6);
		sequence23.add(7);
		sequence23.add(2);
		sequence23.add(5);
		sequence23.add(3);
		sequence23.add(6);
		sequence23.add(6);
		sequence23.add(6);
		sequence23.add(5);
		sequence23.add(3);
		sequence23.add(6);
		sequence23.add(3);

		Level level23 = new Level(23, sequence23, plateau23);

		// Level 23
		List<MatrixPoint> plateau24 = new ArrayList<MatrixPoint>();
		plateau24.add(new MatrixPoint(19, 2, 2));
		plateau24.add(new MatrixPoint(19, 3, 2));
		plateau24.add(new MatrixPoint(19, 4, 2));
		plateau24.add(new MatrixPoint(19, 5, 2));

		List<Integer> sequence24 = new ArrayList<Integer>();
		sequence24.add(5);
		sequence24.add(1);
		sequence24.add(3);
		sequence24.add(6);
		sequence24.add(5);
		sequence24.add(1);
		sequence24.add(5);
		sequence24.add(2);
		sequence24.add(5);
		sequence24.add(1);
		sequence24.add(2);
		sequence24.add(4);
		sequence24.add(6);
		sequence24.add(6);
		sequence24.add(7);
		sequence24.add(5);
		sequence24.add(6);
		sequence24.add(5);
		sequence24.add(3);
		sequence24.add(2);
		sequence24.add(3);
		sequence24.add(6);
		sequence24.add(6);
		sequence24.add(3);

		Level level24 = new Level(24, sequence24, plateau24);

		List<Level> levels = new ArrayList<Level>();
		levels.add(level);
		levels.add(level2);
		levels.add(level3);
		levels.add(level4);
		levels.add(level5);
		levels.add(level6);
		levels.add(level7);
		levels.add(level8);
		levels.add(level9);
		levels.add(level10);
		levels.add(level11);
		levels.add(level12);
		levels.add(level13);
		levels.add(level14);
		levels.add(level15);
		levels.add(level16);
		levels.add(level17);
		levels.add(level18);
		levels.add(level19);
		levels.add(level20);
		levels.add(level21);
		levels.add(level22);
		levels.add(level23);
		levels.add(level24);
		return levels;
	}

	/**
	 * Method allowing to update the JSON Data associated to a given level
	 * 
	 * @param level
	 * @param jsonToObject
	 */
	private void updateLevelJsonData(Level level, boolean jsonToObject) {
		try {
			ObjectMapper mapper = new ObjectMapper();
			if (jsonToObject) {
				Integer[] sequences;
				sequences = mapper.readValue(level.getSequenceJson(), Integer[].class);
				MatrixPoint[] mtxPoints = mapper.readValue(level.getPlateauJson(), MatrixPoint[].class);
				level.setSequence(Arrays.asList(sequences));
				level.setPlateau(Arrays.asList(mtxPoints));
			} else {
				level.setSequenceJson(mapper.writeValueAsString(level.getSequence()));
				level.setPlateauJson(mapper.writeValueAsString(level.getPlateau()));
			}
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
